﻿using System;
using System.Collections.Generic;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit;

namespace YJKArch.Utils
{
	public class ColumnProfileExtractor
	{
		public ColumnProfileExtractor(UIApplication uiApp)
		{
			this.m_uiApplication = uiApp;
			this.m_document = this.m_uiApplication.ActiveUIDocument.Document;
		}

		public List<EdgeInfo> GetColumnProfile(FamilyInstance column)
		{
			LocationPoint locationPoint = column.Location as LocationPoint;
			List<EdgeInfo> list = new List<EdgeInfo>();
			Transform transform = RevitVersionFuncs.CreateTranslation(locationPoint.Point);
			Transform matrix = RevitVersionFuncs.CreateRotationAtPoint(XYZ.BasisZ, locationPoint.Rotation, locationPoint.Point).Multiply(transform);
			Options options = this.m_uiApplication.Application.Create.NewGeometryOptions();
			GeometryElement geometryElement = column.Symbol.get_Geometry(options);
			if (null == geometryElement)
			{
				return list;
			}
			try
			{
				foreach (GeometryObject geometryObject in geometryElement)
				{
					if (!(geometryObject.GetType() != typeof(Solid)))
					{
						Solid solid = geometryObject as Solid;
						if (solid != null)
						{
							List<Curve> list2 = new List<Curve>();
							this.GetBoundary(solid, ref list2);
							foreach (Curve curve in list2)
							{
								EdgeInfo edgeInfo = this.ConvertCurveToEdgeInfo(curve);
								edgeInfo.TransformSelf(matrix);
								list.Add(edgeInfo);
							}
						}
					}
				}
			}
			catch (Exception)
			{
				list.Clear();
				return list;
			}
			return list;
		}

		private XYZ To2D(XYZ pt)
		{
			return new XYZ(pt.X, pt.Y, 0.0);
		}

		private EdgeInfo ConvertCurveToEdgeInfo(Curve curve)
		{
			EdgeInfo result = null;
			XYZ xyz = this.To2D(curve.GetEndPoint(0));
			XYZ xyz2 = this.To2D(curve.GetEndPoint(1));
			Line line = curve as Line;
			if (null != line)
			{
				result = new EdgeInfo(xyz2, xyz, 0.0);
			}
			Arc arc = curve as Arc;
			if (null != arc)
			{
				XYZ centerPt = this.To2D(arc.Center);
				if (!arc.Normal.IsAlmostEqualTo(XYZ.BasisZ))
				{
					XYZ xyz3 = xyz;
					xyz = xyz2;
					xyz2 = xyz3;
				}
				double bulge = Geometry.GetBulge(xyz, xyz2, centerPt, true);
				result = new EdgeInfo(xyz, xyz2, bulge);
			}
			return result;
		}

		private void GetBoundary(Solid solid, ref List<Curve> singleBoundary)
		{
			PlanarFace planarFace = null;
			foreach (object obj in solid.Faces)
			{
				PlanarFace planarFace2 = ((Face)obj) as PlanarFace;
				if (null != planarFace2 && planarFace2.FaceNormal().IsAlmostEqualTo(XYZ.BasisZ) && (null == planarFace || planarFace2.Origin.Z < planarFace.Origin.Z))
				{
					planarFace = planarFace2;
				}
			}
			if (null != planarFace)
			{
				foreach (object obj2 in planarFace.EdgeLoops)
				{
					foreach (object obj3 in ((EdgeArray)obj2))
					{
						Curve curve = ((Edge)obj3).AsCurve();
						if (curve.GetType() == typeof(Line) || curve.GetType() == typeof(Arc))
						{
							singleBoundary.Add(curve);
						}
					}
				}
			}
		}

		private UIApplication m_uiApplication;

		protected Document m_document;
	}
}
